Tengo un esquema de AWS AppSync con el modo de autorización predeterminado establecido en Grupo de usuarios de Amazon Cognito . Realizo llamadas a este punto de enlace de AppSync desde una aplicación web mediante el cliente AWS Amplify GraphQL y, coherentemente, su configuración también señala los grupos de usuarios de Cognito como tipo de autenticación:
aws_appsync_authenticationType: 'AMAZON_COGNITO_USER_POOLS'Funciona como se esperaba cuando el usuario está autenticado ; sin embargo (aunque el conjunto de identidades de Cognito implicado ya tiene establecidos los roles Auth y Unath adecuados), cuando el sitio web ejecuta algún comando de búsqueda de Amplify como para un usuario no autenticado (invitado) :
const item = await API.graphql(graphqlOperation(getItem, { id: 'my-id' }))Termina arrojando un error:
"No current user"Bueno, esperaba que funcionara si permitía usuarios no autenticados, pero simplemente falla. Buscando una salida, encontré algunas discusiones como:
Y, todo lo anterior sugiere revisar las configuraciones de Amplify para que el tipo de autenticación de AppSync se convierta de AMAZON_COGNITO_USER_POOLS a AWS_IAM o API_KEY . Sin embargo, por alguna razón detallada 1 :
AMAZON_COGNITO_USER_POOLS ,@aws_auth o similares.¿Es posible de alguna manera?
1 Tengo controles más granulares según el grupo del usuario (administrador, normal, etc.) con decoradores como @aws_auth(cognito_groups: ["default-user-group"]) en el esquema de AppSync. Entonces, necesito grupos de usuarios de Cognito para ese uso.
Entonces, acabo de pasar por un problema similar y logré solucionarlo. Espero que esto pueda ayudarte a resolver esto. La pregunta SO que mencionó en su pregunta es casi la forma correcta de hacerlo. Sin embargo, hay un "pequeño" pequeño detalle que no está documentado y me llevó un tiempo descubrirlo.
Además de tener que habilitar tanto el acceso autenticado como el no autenticado mediante la ejecución de la amplify update auth (puede ver cómo en el SO vinculado anteriormente), hay otros ajustes que debe hacer.
Primero, en su modelo necesita ajustar sus reglas para que sean algo como:
@auth( rules: [ # allow owners ability to update and delete their these messages (user pools) { allow: owner }, # allow all authenticated users to access this data { allow: private, provider: userPools }, # allow all guest users (not authenticated) to access this data { allow: public, provider: iam } ] )Una vez que configure este modelo para permitir que los grupos de usuarios accedan a todos los datos que "poseen", también puede permitir que cualquier usuario "invitado" acceda a los datos.
En la interfaz, tomemos su código como ejemplo, necesita usar un enfoque un poco diferente:
En vez de
const item = await API.graphql(graphqlOperation(getItem, { id: 'my-id' }))prueba algo como
// Check if the user is logged in or not let isLoggedIn = await isLoggedIn(); const item = (await API.graphql({ query: getItem, variables: { id: 'my-id' }, authMode: isLoggedIn ? GRAPHQL_AUTH_MODE.AMAZON_COGNITO_USER_POOLS : GRAPHQL_AUTH_MODE.AWS_IAM, }));por cierto, la función "isLoggedIn" se ve así
async function isLoggedIn() { // Another way to get if its a guest or not //return await Auth.Credentials.getCredSource() === "guest" try { await Auth.currentAuthenticatedUser(); return true; } catch { return false; } }Entonces... esta línea es lo que funciona, lo cual no está muy bien documentado.
authMode: isLoggedIn ? GRAPHQL_AUTH_MODE.AMAZON_COGNITO_USER_POOLS : GRAPHQL_AUTH_MODE.AWS_IAM
debe enrutar los diferentes métodos según el estado del usuario (iniciado sesión o invitado), no solo el de AWS_IAM.
Esto solo lo llevará hasta LEER los datos, para asegurarse de que los invitados puedan crear / actualizar / eliminar, y separar la propiedad de los datos entre sí y los usuarios registrados, esa es una historia completamente diferente que deberá comenzar a cavar. en resolutores para ordenarlo. Pero la buena noticia es que hay una manera :)